package vn.mahjonggame.game.request;

import java.util.Iterator;
import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import org.apache.log4j.Logger;

import vn.mahjonggame.game.Mahjong;
import vn.mahjonggame.game.MahjongExtension;
import vn.mahjonggame.metadata.GameActionType;
import vn.mahjonggame.metadata.Player;
import vn.mahjonggame.metadata.MObject;
import vn.mahjonggame.metadata.Response;
import vn.mahjonggame.metadata.RoomVarName;
import vn.mahjonggame.metadata.Tile;
import vn.mahjonggame.metadata.TileSet;
import vn.mahjonggame.metadata.UserVarName;
import vn.mahjonggame.platform.PlatformConfig;

import com.smartfoxserver.v2.entities.Room;
import com.smartfoxserver.v2.entities.User;
import com.smartfoxserver.v2.entities.data.ISFSObject;
import com.smartfoxserver.v2.entities.data.SFSArray;
import com.smartfoxserver.v2.entities.data.SFSObject;
import com.smartfoxserver.v2.extensions.BaseClientRequestHandler;
import com.smartfoxserver.v2.extensions.ExtensionLogLevel;

public class CancelKanHandler extends BaseClientRequestHandler {

	@Override
	public void handleClientRequest(final User user, ISFSObject params) {
		final MahjongExtension ext = (MahjongExtension) getParentExtension();
		final Mahjong mahjong = ext.getMahjong();
		Logger logger = mahjong.getLogger();
		Room room = getParentExtension().getParentRoom();
		final List<User> users = user.getLastJoinedRoom().getUserList();		
		
		String kanType = params.getUtfString(MObject.kanType.toString());
				
		final Player player = mahjong.getPlayerById(user.getId());		
		
		player.setHasThrown(false);
		
		logger.info(mahjong.log(room, player, GameActionType.cancelKan.toString(), "kanType: " + kanType));			
		
		Tile tile = null;			
		
		Player thrownPlayer = null;
		Player nextTurnPlayer = null;	
		
		if(!kanType.equalsIgnoreCase(TileSet.OPENKAN.toString())){
			tile = player.getJustPickedTile();
			nextTurnPlayer = player;
		}
		else {
			thrownPlayer = mahjong.getThrownPlayer();
			nextTurnPlayer = mahjong.getNextPlayer(thrownPlayer);
			tile = thrownPlayer.getJustThrownTile();
		}
		
		Response.Builder response = new Response.Builder();
		response.nextPosition(player.getPlayerPosition())
				.position(player.getPlayerPosition())
				.tile(tile.getId())
				.type(kanType)
				.turn(nextTurnPlayer.getPlayerPosition());
		
		/*
		if(kanType.equalsIgnoreCase(TileSet.OPENKAN.toString())){
			
			/*
			 * Check if the next player can call CHI
			 *
			List<List<Tile>> tileIds = nextTurnPlayer.checkChi(thrownPlayer.getJustThrownTile());
			
			if(tileIds.size() > 0 && !nextTurnPlayer.isDisconnect()){
				
				Response.Builder subResponse = new Response.Builder();
				
				subResponse.losePos(player.getPlayerPosition())
							.winPos(nextTurnPlayer.getPlayerPosition())
							.loseTile(tile.getId());
				
				SFSArray tileIdSFSArray = new SFSArray();
				for(int i = 0; i < tileIds.size(); i++){
					tileIdSFSArray.addIntArray(mahjong.tileArrayToTileIdArray(tileIds.get(i)));
				}
				
				subResponse.winTile(tileIdSFSArray);							
				
				response.CHI(subResponse.build().getSFSObject());
			}
		}
		*/
	
		send(GameActionType.cancelKan.toString(), response.build().getSFSObject(), user);
		
		nextTurnPlayer.setHasPicked(false);
		mahjong.setPlayerInTurn(nextTurnPlayer);
		
		ext.addAction(user, GameActionType.cancelKan.toString());		
				
		/*
		 * Check if any other player is waiting for calling CHI
		 */
		Player callingChiPlayer = mahjong.getCallingChiPlayer();		
		if(callingChiPlayer != null){
			mahjong.callChi(ext, users, room, callingChiPlayer);
			mahjong.setCallingChiPlayer(null);
			logger.info(mahjong.log(room, player, GameActionType.cancelKan.toString(), "Call CHI for the waiting player " + callingChiPlayer.toString()));
			return;
		}		
		
		if(player.isDisconnect() || Boolean.valueOf(room.getVariable(RoomVarName.is_auto.toString()).getStringValue())){
			/*
			 * Wait 5 second. If player does not thrown the tile, auto thrown the tile
			 */			
			final Response.Builder nextParams = new Response.Builder();
			
			int delay = player.getTurnTime() + player.getBonusTime();	
			/*
			 * Only wait 1 second if the player is disconnected
			 */
			if(player.isDisconnect()){
				delay = 1000;
			}
			logger.info(mahjong.log(room, player, GameActionType.cancelKan.toString(), "isDisconnect: " + player.isDisconnect()));
			
			if(!kanType.equalsIgnoreCase(TileSet.OPENKAN.toString())){
				
				logger.info(mahjong.log(room, player, GameActionType.cancelKan.toString(), "Calling throw handler: " + delay));
				
				final Tile tileCopy = tile;
				nextParams.tile(tileCopy.getId());				
				
				Timer timer = player.getTimer();
				timer.schedule(new TimerTask() {
					  @Override
					  public void run() {
						  if(!player.isHasThrown()){
							  ThrowTileHandler throwTileHandler = new ThrowTileHandler();					  
							  throwTileHandler.throwTile(ext, user, nextParams.build().getSFSObject(), true, false);
						  }			
					  }
				}, delay);
			}
			else {
				final Player callingPickPlayer = mahjong.getCallingPickPlayer();
				logger.info(mahjong.log(room, player, GameActionType.cancelKan.toString(), "CallingPickPlayer: " + callingPickPlayer));
				
				nextParams.kanType(kanType);
				
				if(callingPickPlayer != null && !mahjong.isHasPickedTile()){
					Timer timer = player.getTimer();
					timer.schedule(new TimerTask() {
						  @Override
						  public void run() {
							  PickTileHandler pickTileHanlder = new PickTileHandler();
							  pickTileHanlder.pickTile(ext, mahjong.getUserByPlayerId(callingPickPlayer.getPlayerId(), users), nextParams.build().getSFSObject(), false); 
						  }
					}, 1000);					
				}
			}
		}		
	}
}
